]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
status: Port to a new SystemIndicator framework
authorJasper St. Pierre <jstpierre@mecheye.net>
Thu, 6 Jun 2013 21:27:25 +0000 (17:27 -0400)
committerJasper St. Pierre <jstpierre@mecheye.net>
Tue, 13 Aug 2013 10:50:24 +0000 (06:50 -0400)
We can't silently replace the old behavior of separate status
icons into a new system. Replace SystemStatusButton with a new
SystemIndicator class which will allow for the flexibility we
need. For now, make it a subclass of Button so that it mostly
feels the same, but we'll soon be swapping it out with a dummy
implementation that the aggregate menu will use.

I think the code cleanup here is worth it.

https://bugzilla.gnome.org/show_bug.cgi?id=705845

data/theme/gnome-shell.css
js/gdm/powerMenu.js
js/ui/panelMenu.js
js/ui/status/bluetooth.js
js/ui/status/lockScreenMenu.js
js/ui/status/network.js
js/ui/status/power.js
js/ui/status/system.js
js/ui/status/volume.js

index 46b5a75bb40238480840bd6547738ae504585c30..a63c5e739a150dc0e8b6219bba8580e72dd85e86 100644 (file)
@@ -614,7 +614,7 @@ StScrollBar StButton#vhandle:active {
     -boxpointer-gap: 4px;
 }
 
-.panel-status-button-box,
+.panel-status-indicators-box,
 .panel-status-menu-box {
     spacing: 4px;
 }
index a341619fd94adbbba6bbf4f5a6bc81f70bace696..487c1c6fe78891d6712adeef6007e179986ed2e9 100644 (file)
@@ -29,7 +29,7 @@ const PopupMenu = imports.ui.popupMenu;
 
 const PowerMenuButton = new Lang.Class({
     Name: 'PowerMenuButton',
-    Extends: PanelMenu.SystemStatusButton,
+    Extends: PanelMenu.SystemIndicator,
 
     _init: function() {
         /* Translators: accessible name of the power menu in the login screen */
index d77143b1704cd5d608214a7345355b79c18e3d54..fb215663101bbcbe42036dd812b5db4f0ac970af 100644 (file)
@@ -233,51 +233,29 @@ const Button = new Lang.Class({
 });
 Signals.addSignalMethods(Button.prototype);
 
-/* SystemStatusButton:
+/* SystemIndicator:
  *
- * This class manages one System Status indicator (network, keyboard,
- * volume, bluetooth...), which is just a PanelMenuButton with an
- * icon.
+ * This class manages one system indicator, which are the icons
+ * that you see at the top right. A system indicator is composed
+ * of an icon and a menu section, which will be composed into the
+ * aggregate menu.
  */
-const SystemStatusButton = new Lang.Class({
-    Name: 'SystemStatusButton',
+const SystemIndicator = new Lang.Class({
+    Name: 'SystemIndicator',
     Extends: Button,
 
-    _init: function(iconName, nameText) {
-        this.parent(0.0, nameText);
+    _init: function() {
+        this.parent(0.0);
         this.actor.add_style_class_name('panel-status-button');
 
-        this._box = new St.BoxLayout({ style_class: 'panel-status-button-box' });
-        this.actor.add_actor(this._box);
-
-        if (iconName)
-            this.setIcon(iconName);
-    },
-
-    get icons() {
-        return this._box.get_children();
+        this.indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' });
+        this.actor.add_actor(this.indicators);
     },
 
-    addIcon: function(gicon) {
+    addIndicator: function(gicon) {
         let icon = new St.Icon({ gicon: gicon,
                                  style_class: 'system-status-icon' });
-        this._box.add_actor(icon);
-
-        this.emit('icons-changed');
-
+        this.indicators.add_actor(icon);
         return icon;
-    },
-
-    setIcon: function(iconName) {
-        if (!this.mainIcon)
-            this.mainIcon = this.addIcon(null);
-        this.mainIcon.icon_name = iconName;
-    },
-
-    setGIcon: function(gicon) {
-        if (this.mainIcon)
-            this.mainIcon.gicon = gicon;
-        else
-            this.mainIcon = this.addIcon(gicon);
     }
 });
index f2db976252adbe01465a902f59025bb7fa96da73..29f8ad811b227cb76af2f79c1ab85c8ec7b38c3c 100644 (file)
@@ -15,10 +15,12 @@ const PopupMenu = imports.ui.popupMenu;
 
 const Indicator = new Lang.Class({
     Name: 'BTIndicator',
-    Extends: PanelMenu.SystemStatusButton,
+    Extends: PanelMenu.SystemIndicator,
 
     _init: function() {
-        this.parent('bluetooth-disabled-symbolic', _("Bluetooth"));
+        this.parent();
+
+        this._indicator = this.addIndicator(new Gio.ThemedIcon({ name: 'bluetooth-active-symbolic' }));
 
         // The Bluetooth menu only appears when Bluetooth is in use,
         // so just statically build it with a "Turn Off" menu item.
@@ -47,8 +49,8 @@ const Indicator = new Lang.Class({
         let nDevices = connectedDevices.length;
 
         let on = nDevices > 0;
-        this.mainIcon.visible = on;
-        this.actor.visible = on;
+        this._indicator.visible = on;
+        this._item.actor.visible = on;
 
         if (on)
             this._item.status.text = ngettext("%d Connected Device", "%d Connected Devices").format(nDevices);
index e9ee6fda72d959163a5ce9b8c6c0bf2f50382e12..a735ae82ea11eb4070351c290b840c0078603ba8 100644 (file)
@@ -37,26 +37,26 @@ const FakeStatusIcon = new Lang.Class({
 
 const Indicator = new Lang.Class({
     Name: 'LockScreenMenuIndicator',
-    Extends: PanelMenu.SystemStatusButton,
+    Extends: PanelMenu.SystemIndicator,
 
     _init: function() {
         this.parent(null, _("Volume, network, battery"));
-        this._box.style_class = 'lock-screen-status-button-box';
+        this.indicators.style_class = 'lock-screen-status-button-box';
 
         this._volumeControl = VolumeMenu.getMixerControl();
         this._volumeMenu = new VolumeMenu.VolumeMenu(this._volumeControl);
         this.menu.addMenuItem(this._volumeMenu);
 
         this._volume = new FakeStatusIcon(Main.panel.statusArea.volume);
-        this._box.add_child(this._volume.actor);
+        this.indicators.add_child(this._volume.actor);
 
         // Network may not exist if the user doesn't have NetworkManager
         if (Main.panel.statusArea.network) {
             this._network = new FakeStatusIcon(Main.panel.statusArea.network);
-            this._box.add_child(this._network.actor);
+            this.indicators.add_child(this._network.actor);
         }
 
         this._battery = new FakeStatusIcon(Main.panel.statusArea.battery);
-        this._box.add_child(this._battery.actor);
+        this.indicators.add_child(this._battery.actor);
     }
 });
index 751711823f536b84561c44eb1b69a81ae41c6e8a..9c03eeb7c5e7455b6a3ace6c725127b93e8021ae 100644 (file)
@@ -1152,12 +1152,13 @@ Signals.addSignalMethods(NMVPNSection.prototype);
 
 const NMApplet = new Lang.Class({
     Name: 'NMApplet',
-    Extends: PanelMenu.SystemStatusButton,
+    Extends: PanelMenu.SystemIndicator,
 
     _init: function() {
-        this.parent('network-offline-symbolic', _('Network'));
+        this.parent();
 
-        this._vpnIcon = this.addIcon(null);
+        this._primaryIndicator = this.addIndicator(null);
+        this._vpnIndicator = this.addIndicator(null);
 
         // Device types
         this._dtypes = { };
@@ -1579,29 +1580,27 @@ const NMApplet = new Lang.Class({
     },
 
     _syncNMState: function() {
-        this.mainIcon.visible = this._client.manager_running;
-        this.actor.visible = this.mainIcon.visible;
-
         this._syncActiveConnections();
+
+        this.indicators.visible = this._client.manager_running;
         this._section.actor.visible = this._client.networking_enabled;
     },
 
     _updateIcon: function() {
-        let hasApIcon = false;
-        let hasMobileIcon = false;
+        let mc = this._mainConnection;
 
-        if (!this._client.networking_enabled || !this._mainConnection) {
-            this.setIcon('network-offline-symbolic');
+        if (!this._client.networking_enabled || !mc) {
+            this._primaryIndicator.icon_name = 'network-offline-symbolic';
         } else {
             let dev = this._mainConnection._primaryDevice;
             if (!dev) {
                 log('Active connection with no primary device?');
                 return;
             }
-            this.setIcon(dev.getIndicatorIcon());
+            this._primaryIndicator.icon_name = dev.getIndicatorIcon(mc);
         }
 
-        this._vpnIcon.icon_name = this._vpnSection.getIndicatorIcon();
-        this._vpnIcon.visible = (this._vpnIcon.icon_name != '');
+        this._vpnIndicator.icon_name = this._vpnSection.getIndicatorIcon();
+        this._vpnIndicator.visible = (this._vpnIndicator.icon_name != '');
     }
 });
index 3e7681671685af31405933aedaa1fc5bb1ae2ec8..f38c0bb3da7028ede8c2934800df202965f6f80b 100644 (file)
@@ -25,10 +25,12 @@ const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(PowerManagerInterface);
 
 const Indicator = new Lang.Class({
     Name: 'PowerIndicator',
-    Extends: PanelMenu.SystemStatusButton,
+    Extends: PanelMenu.SystemIndicator,
 
     _init: function() {
-        this.parent('battery-missing-symbolic', _("Battery"));
+        this.parent();
+
+        this._indicator = this.addIndicator(null);
 
         this._proxy = new PowerManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
                                             Lang.bind(this, function(proxy, error) {
@@ -104,16 +106,14 @@ const Indicator = new Lang.Class({
 
     _syncIcon: function() {
         let icon = this._proxy.Icon;
-        let hasIcon = false;
-
         if (icon) {
             let gicon = Gio.icon_new_for_string(icon);
-            this.setGIcon(gicon);
+            this._indicator.gicon = gicon;
+            this._indicator.show();
             this._item.icon.gicon = gicon;
-            hasIcon = true;
+        } else {
+            this._indicator.hide();
         }
-        this.mainIcon.visible = hasIcon;
-        this.actor.visible = hasIcon;
     },
 
     _sync: function() {
index 8e889dcc497be3a9170e38581091f0e03fd5e500..74ab786d9ba588d22ff05a2066e69a52492c70d9 100644 (file)
@@ -42,10 +42,12 @@ const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIf
 
 const Indicator = new Lang.Class({
     Name: 'SystemIndicator',
-    Extends: PanelMenu.SystemStatusButton,
+    Extends: PanelMenu.SystemIndicator,
 
     _init: function() {
-        this.parent('system-shutdown-symbolic', _("System"));
+        this.parent();
+
+        this._indicator = this.addIndicator(new Gio.ThemedIcon({ name: 'system-shutdown-symbolic' }));
 
         this._screenSaverSettings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
         this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA });
index 58c5ec67d8249e524b5ab3dcd49e364b75db1e11..5a9fed964f3b0eb7a00366af9bdc2671f932ca9b 100644 (file)
@@ -296,22 +296,29 @@ const VolumeMenu = new Lang.Class({
 
 const Indicator = new Lang.Class({
     Name: 'VolumeIndicator',
-    Extends: PanelMenu.SystemStatusButton,
+    Extends: PanelMenu.SystemIndicator,
 
     _init: function() {
-        this.parent('audio-volume-muted-symbolic', _("Volume"));
+        this.parent();
+
+        this._primaryIndicator = this.addIndicator(null);
 
         this._control = getMixerControl();
         this._volumeMenu = new VolumeMenu(this._control);
         this._volumeMenu.connect('icon-changed', Lang.bind(this, function(menu) {
             let icon = this._volumeMenu.getIcon();
-            this.actor.visible = (icon != null);
-            this.setIcon(icon);
+
+            if (icon != null) {
+                this.indicators.show();
+                this._primaryIndicator.icon_name = icon;
+            } else {
+                this.indicators.hide();
+            }
         }));
 
         this.menu.addMenuItem(this._volumeMenu);
 
-        this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
+        this.indicators.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
     },
 
     _onScrollEvent: function(actor, event) {